﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Xml;
using System.Reflection;
using LogLib;
using AppDataStruct;

namespace PrintExcel
{
    /// <summary>
    /// 身份证信息类
    /// </summary>
    public class SFZMerge
    {
        public string AssemblyDirectory
        {
            get
            {
                return Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);
            }
        }

        private string _sfzzmPicPath = "";

        private string _sfzfmPicPath = "";

        private SFZInfo _data = new SFZInfo();

        private string _error = "";
        public string ErrorMessage
        {
            get { return _error; }
        }

        public SFZMerge()
        {
            _sfzzmPicPath = Path.Combine(AssemblyDirectory, "SFZPicture", "sfzzm.jpg");
            _sfzfmPicPath = Path.Combine(AssemblyDirectory, "SFZPicture", "sfzfm.jpg");
        }

        /// <summary>
        /// 从给定的身份证信息文件读取数据并初始化
        /// </summary>
        /// <param name="SFZInfoFilePath"></param>
        public SFZMerge(SFZInfo data) : this()
        {
            _data = data;
        }

        /// <summary>
        /// 复姓字
        /// </summary>
        private static string[] MultiName = new string[]
        {
            "欧阳","太史","端木","上官","司马","东方","独孤","南宫","万俟","闻人","夏侯","诸葛","尉迟","公羊","赫连","澹台",
            "皇甫","宗政","濮阳","公冶","太叔","申屠","公孙","慕容","仲孙","钟离","长孙","宇文","城池","司徒","鲜于","司空",
            "闾丘","子车","亓官","司寇","巫马","公西","颛孙","壤驷","公良","漆雕","乐正","宰父","谷梁","拓跋","夹谷","轩辕",
            "令狐","段干","百里","呼延","东郭","南门","羊舌","微生","公户","公玉","公仪","梁丘","公仲","公上","公门","公山",
            "公坚","左丘","公伯","西门","公祖","第五","公乘","贯丘","公皙","南荣","东里","东宫","仲长","子书","子桑","即墨",
            "达奚","褚师"
        };

        /// <summary>
        /// 合成身份证反面图片
        /// </summary>
        /// <param name="RawPicturePath">无信息正面图片</param>
        /// <param name="PersonPicturePath">人员头像图片路径</param>
        /// <returns></returns>
        public Bitmap MergeSFZBackPicture()
        {
            try
            {
                Bitmap bpPicture = new Bitmap(Image.FromFile(_sfzzmPicPath));
                Graphics gcNow = Graphics.FromImage(bpPicture);
                Brush bhMap = new SolidBrush(Color.Black);

                System.Drawing.Font font1 = new System.Drawing.Font("黑体", 18); 
                System.Drawing.Font font2 = new System.Drawing.Font("黑体", 20);
                System.Drawing.Font font3 = new System.Drawing.Font("方正黑体", 18);

                //姓名
                gcNow.DrawString(_data.Name, font2, bhMap, new System.Drawing.Point(125, 62));                
                
                //性别
                gcNow.DrawString(_data.Sex, font1, bhMap, new System.Drawing.Point(125, 115));                
                
                //民族
                gcNow.DrawString(_data.Nation, font1, bhMap, new System.Drawing.Point(265, 115));
                
                //出生日期
                gcNow.DrawString(_data.BirthYear, font3, bhMap, new System.Drawing.Point(125, 164));//年  
                gcNow.DrawString(_data.BirthMonth, font3, bhMap, new System.Drawing.Point(234, 164));//月
                gcNow.DrawString(_data.BirthDay, font3, bhMap, new System.Drawing.Point(295, 164));//日
                
                //地址(宽300)
                int StartIndex = 0;
                float InitialX = 125,InitialY = 192, NowY, NowLineNum = 1;
                string TempAddress;
                SizeF sfTempAddress;
                for (int i = 0; i < _data.Address.Length; i++)
                {
                    TempAddress = _data.Address.Substring(StartIndex, i - StartIndex + 1);
                    sfTempAddress = gcNow.MeasureString(TempAddress, font1);
                    if (sfTempAddress.Width >= 270 || i == _data.Address.Length - 1)
                    {
                        //写入该行
                        NowY = InitialY + (NowLineNum - 1) * sfTempAddress.Height + 30;
                        gcNow.DrawString(TempAddress, font1, bhMap, new PointF(InitialX, NowY));
                        
                        NowLineNum++;
                        StartIndex = i + 1;
                    }
                }
                
                #region 身份证号码
                //使用OCR-B 10 BT字体
                System.Drawing.Font ftSFZH = new System.Drawing.Font("OCR-B 10 BT", 20, FontStyle.Bold);

                //字符间距
                float CharMargin = (220 - gcNow.MeasureString(_data.SFZH, ftSFZH).Width) / (_data.SFZH.Length - 1);
                
                //逐个字符绘制
                PointF ptNow = new PointF(230,355);
                foreach (char crNow in _data.SFZH)
                {
                    gcNow.DrawString(crNow.ToString(), ftSFZH, bhMap, ptNow);

                    ptNow.X += gcNow.MeasureString(crNow.ToString(), ftSFZH).Width + CharMargin;
                }
                #endregion

                //人员头像
                if (File.Exists(_data.HeaderPicturePath))
                {
                    Image imgPerson = Image.FromFile(_data.HeaderPicturePath);
                    //去除头像白色背景
                    imgPerson = RemoveWhiteBackColor(imgPerson);
                    gcNow.DrawImage(imgPerson, new RectangleF(423, 63, 215, 268), new RectangleF(0, 0, imgPerson.Width, imgPerson.Height), GraphicsUnit.Pixel);
                }
                else
                {
                    Log.WriteAsync("不存在的身份证头像照片: " + _data.HeaderPicturePath);
                }
                return bpPicture;
            }
            catch(Exception ex)
            {
                _error = ex.Message;
                Log.WriteAsync("生成[[" + _data.Name + "]身份证正面图片失败:" + ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 获取身份证反面图片
        /// </summary>
        /// <param name="RawPicturePath">无信息背面图片</param>
        /// <returns></returns>
        public Bitmap MergeSFZFrontPicture()
        {
            try
            {
                Bitmap bpPicture = new Bitmap(Image.FromFile(_sfzfmPicPath));
                Graphics gcNow = Graphics.FromImage(bpPicture);
                System.Drawing.Font font1 = new System.Drawing.Font("黑体", 18); 
                System.Drawing.Font font2 = new System.Drawing.Font("方正黑体", 18);
                Brush bhMap = new SolidBrush(Color.Black);

                //发证机关
                gcNow.DrawString(_data.IssueUnit, font1, bhMap, new System.Drawing.Point(265, 308));

                //起止有效日期
                gcNow.DrawString(_data.ExpiryStartDate + "-" + _data.ExpiryEndDate, font2, bhMap, new System.Drawing.Point(265, 362));
                return bpPicture;
            }
            catch(Exception ex)
            {
                _error = ex.Message;
                Log.WriteAsync("生成[[" + _data.Name + "]身份证正面图片失败:" + ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 去除白色背景色
        /// </summary>
        /// <param name="imgSource"></param>
        /// <returns></returns>
        public Image RemoveWhiteBackColor(Image imgSource)
        {
            try
            {
                Bitmap bpSource = new Bitmap(imgSource);
                //返回用照片
                Bitmap bpReturn = new Bitmap(imgSource.Width, imgSource.Height, PixelFormat.Format32bppArgb);
                Color clNowPoint, clTransparent = Color.FromArgb(0, 255, 255, 255);
                for (int i = 0; i < bpReturn.Width; i++)
                {
                    for (int j = 0; j < bpReturn.Height; j++)
                    {
                        clNowPoint = bpSource.GetPixel(i, j);
                        //白底
                        if (clNowPoint.R > 245 && clNowPoint.G > 245 && clNowPoint.B > 245 && clNowPoint.A == 255)
                            bpReturn.SetPixel(i, j, clTransparent);
                        else
                            bpReturn.SetPixel(i, j, clNowPoint);
                    }
                }

                return bpReturn;
            }
            catch
            {
                return imgSource;
            }
        }
   
      
      
    }

}
